package com.chen.common.util;

import com.chen.common.model.OP;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;

/**
 * @author ex_chenzy59
 * @since 2025/2/27
 * jackJson工具类:
 */
@Slf4j
public class JsonUtil {
    private static SimpleModule _simpleModule;
    private static ObjectMapper _objectMapper = getObjectMapper();

    public synchronized static SimpleModule getSimpleModule(){
        if (_simpleModule ==null){
            _simpleModule = new SimpleModule();
            init(_simpleModule);
        }
        return _simpleModule;
    }
    private static void init(SimpleModule simpleModule){
        /*反序列化：string=>对象*/
        /*去除首尾空格,空字符串返回null*/
        simpleModule.addDeserializer(String.class, new StdScalarDeserializer<String>(String.class) {
            @Override
            public String deserialize(JsonParser p, DeserializationContext ctxt)
                    throws IOException {
                String text= p.getText().trim();
                if (StringUtil.isBlank(text)){
                    return null;
                }
                return text;
            }
        });
        /*序列化：对象=>string*/
    }
    protected static ObjectMapper createObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        /*忽略null字段*/
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        /*允许json属性名不使用双引号*/
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        /*忽略不存在字段*/
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//        /*允许空字符串作为null*/
//        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,true);
//        /*允许单独字符串映射为数组*/
        objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

        objectMapper.registerModule(getSimpleModule());
        return objectMapper;
    }
    public synchronized static ObjectMapper getObjectMapper() {
        if (_objectMapper == null) {
            _objectMapper = createObjectMapper();
        }
        return _objectMapper;
    }
    public static OP<String> model2Str(Object model) {
        if (model == null) {
            return OP.empty();
        }
        if (ClassUtil.isBasicType(model.getClass())) {
            return OP.of(model.toString());
        }
        try {
            return OP.of(_objectMapper.writeValueAsString(model));
        } catch (JsonProcessingException e) {
            log.error("对象转字符串异常:", e);
            return OP.empty();
        }
    }
    public static <S> String model2StrDefault(S model, String defaultStr) {
        if (model == null) {
            return defaultStr;
        }
        if (ClassUtil.isBasicType(model.getClass())) {
            return model.toString();
        }
        try {
            return _objectMapper.writeValueAsString(model);
        } catch (JsonProcessingException e) {
            log.error("对象转换异常:", e);
            return defaultStr;
        }
    }

    public static <T> OP<T> str2Model(String text, TypeReference<T> tTypeReference){
        try {
            return OP.of(_objectMapper.readValue(text, tTypeReference));
        } catch (IOException e) {
            log.error("字符串转对象异常:", e);
            return OP.empty();
        }
    }

    public static <T1,T2> OP<T1> str2Model(String text,Class<T1> tClass,Class<T2> tClass2){
        try {
            return OP.of(_objectMapper.readValue(text, getJavaType(tClass,tClass2)));
        } catch (IOException e) {
            log.error("字符串转对象异常:", e);
            return OP.empty();
        }
    }
    public static JavaType getJavaType(Class<?> parametrized, Class<?>... parameterClasses){
        return _objectMapper.getTypeFactory().constructParametricType(parametrized, parameterClasses);
    }
    public static <T> OP<T> str2Model(String text,Class<T> tClass){
        try {
            return OP.of(_objectMapper.readValue(text, tClass));
        } catch (IOException e) {
            log.error("字符串转对象异常:", e);
            return OP.empty();
        }
    }
    public static<T> List<T> str2List(String content, Class<T> tClass) {
        return str2Model(content, new TypeReference<List<T>>() {}).orElse(List.of());
    }
    /**
     * 对象=>另一个对象
     */
    public static <Source, Target> OP<Target> model2Model(Source model, Class<Target> targetClass) {
        if (model == null || targetClass == null) {
            return OP.empty();
        }
        @SuppressWarnings("unchecked")
        var srcClass = (Class<Source>) model.getClass();
        //对象是Target类型或子类，
        if (ClassUtil.isType(srcClass, targetClass)) {
            return OP.of(targetClass.cast(model));
        }
        if (model instanceof String) {
            try {
                return OP.ofNullable(_objectMapper.readValue((String) model, targetClass));
            } catch (JsonProcessingException e) {
                log.error("对象转换异常:", e);
                return OP.empty();
            }
        }
        return OP.ofNullable(_objectMapper.convertValue(model, targetClass));
    }

}
